/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package iluscodelogica;

import excepciones.InterpreteException;
import java.util.ArrayList;

/**
 * CLASE QUE COMUNICA A LA GRAFICA LAS ACCIONES Y ESPERA LECTURA DE LOS SENSORES 
 * 
 * @author IlusCode Software para aprender a programar
 */
public class Robot implements Sujeto {

    static final Integer intervaloReposo = new Integer(100);
    static int intervalo;    
    int direccion;
    Algoritmo algoritmo;    
    private ArrayList misObservadores = new ArrayList();
    boolean hayObstaculo = false;    
    String mje = "";
    boolean obstaculo = false;
    boolean ladron=false;
    boolean fuego=false;
    MaquinaVirtual mv;
    private String instruccion;
    private boolean detectaObstaculo;
    private int velocidad=500;
    
    public Robot(){
        
    }

    

    /**
     * 
     * @param a
     */
    public void setAlgoritmo(Algoritmo a) {
        algoritmo = a;
    }    
  
    /**
     * 
     * Metodo que crea el hilo de ejecución en la maquina virtual
     * 
     */
    public void start() {

        mv = new MaquinaVirtual(this, algoritmo);
        mv.start();

    }

    /**
     * 
     * Metodo para detenen el hilo de ejecución
     * 
     */
    public void detenerHilo() {
        mv.stop();

    }
   

    /**
     * 
     * 
     * 
     * @param a
     * @return
     * @throws InterpreteException
     */
    public boolean ejecutar(Algoritmo a) throws InterpreteException {
        algoritmo = a;
        start();
        return true;
    }

    private void reposo() {
        try {
            Thread.sleep(400);
        } catch (InterruptedException e) {
        }
    }

    private void reposo(int mili) {
        try {
            Thread.sleep(mili);
        } catch (InterruptedException e) {
        }
    }  

   


    /**
     * Metodo que comunica a la grafica la acción avanzar
     * 
     * @throws InterpreteException
     */
    public void avanzar()  {
        

        if (!this.obstaculo) {

            
            this.instruccion = "avanzar";
            notificarObservador();
        } else {
            
            String mensaje = ("Se me impide continuar"); 
           
            detenerHilo();         
           
             

        }
        reposo(velocidad);
    }

    /**
     * Metodo que comunica a la grafica la acción girarOeste
     * 
     */
    public void girarOeste() {

        this.instruccion = "giraroeste";

        notificarObservador();

        reposo(intervaloReposo);
    }

    /**
     * Metodo que comunica a la grafica la acción girarEste
     * 
     */
    public void girarEste() {
        
        this.instruccion = "girareste";

        notificarObservador();

        reposo(intervaloReposo);
    }

    /**
     * Metodo que comunica a la grafica la acción girarNorte
     * 
     */
    public void girarNorte() {
        
        this.instruccion = "girarnorte";

        notificarObservador();

        reposo(intervaloReposo);
    }

    /**
     * Metodo que comunica a la grafica la acción girarSur
     * 
     */
    public void girarSur() {

        this.instruccion = "girarsur";

        notificarObservador();

        reposo(intervaloReposo);
    }

    /**
     * 
     * Metodo que comunica a la grafica la acción detener el robot
     * 
     */
    public void detener() {
        
        this.instruccion="detener";
        notificarObservador();
        reposo(intervaloReposo);
    }

    /**
     * 
     * Metodo que detecta si hay obstaculo 
     * 
     * @return
     */
    public boolean DetectaObstaculo() {

        this.instruccion = "hayobstaculo";
        notificarObservador();
        reposo(intervaloReposo);

        return this.obstaculo;
    }
    
    /**
     * 
     * Metodo que detecta si hay fuego
     * 
     * @return
     */
    public boolean DetectaFuego(){
        this.instruccion="hayfuego";
        notificarObservador();
        reposo(intervaloReposo);
        
        return this.fuego;
    }
    
    /**
     * 
     * Metodo que detecta si hay ladron
     * 
     * @return
     */
    public boolean DetectaLadron(){
        this.instruccion="hayladron";
        notificarObservador();
        reposo(intervaloReposo);
        return this.ladron;
    }
    
    //Metodo que comunica a la grafica la acción cerrar Cerramiento
    
    public void cerrarCerramiento(){
        
        this.instruccion = "cerrarCerramiento";

        notificarObservador();

        reposo(intervaloReposo);
        
    }
    
    //Metodo que comunica a la grafica la acción activarAlarma
    
    public void activarAlarma(){
        this.instruccion="activaralarma";
        notificarObservador();
        reposo(intervaloReposo);
    }

    /**
     * Metodo que agrega observadores
     * 
     * @param obs
     */
    @Override
    public void agregarObservador(Observador obs) {

        misObservadores.add(obs);

    }

    /**
     * 
     * Metodo que remueve observadores
     * 
     * @param obs
     */
    @Override
    public void removerObservador(Observador obs) {
        
        misObservadores.remove(obs);

    }

    /**
     * 
     * Metodo que notifica a los observadores
     * 
     */
    @Override
    public void notificarObservador() {
        if (misObservadores != null) {
            for (int i = 0; i < misObservadores.size(); i++) {
                Observador observador = (Observador) misObservadores.get(i);                
                observador.actualizar(this.instruccion);
            }
        }
    }

    /**
     * 
     * Metodo que solicita lectura de los senores de la grafica
     * 
     * @param obstaculo
     * @param fuego
     * @param ladron
     */
    @Override
    public void solicitarInformacion(boolean obstaculo,boolean fuego, boolean ladron) {

        this.obstaculo = obstaculo;
        this.fuego=fuego;
        this.ladron=ladron;        

    }  

    /**
     * 
     * Metodo que solicita la velocidad establecida en la grafica
     * 
     * @param v
     */
    @Override
    public void solicitarVelocidad(int v) {
        velocidad=v;
    }
}
